﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ServiceModel;
using System.Data.SqlClient;
using LocalServerApp.RemoteServerService;
using LocalServerApp.Backup;



namespace LocalServerApp
{
    public class LocalServerService : ILocalServerService
    {
        private static readonly List<IEndSessionCallback> subscribers = new List<IEndSessionCallback>();
        private XmlWardrobeBackup backup = new XmlWardrobeBackup();

        public LocalServerService()
        {
            Console.WriteLine("STARTED");
        }

        public void endSession()
        {
            DAO.getInstance().endSession();
            subscribers.ForEach(delegate(IEndSessionCallback callback)
            {
                if (((ICommunicationObject)callback).State == CommunicationState.Opened)
                {
                    Console.WriteLine("Send endSession to:(tostring) " + ((ICommunicationObject)callback).ToString());

                    Console.WriteLine("Send endSession to:(state) " + ((ICommunicationObject)callback).State);
                    callback.OnEndSession();
                }
                else
                {
                    subscribers.Remove(callback);
                }
            });
        }

        public bool subscribe()
        {
            try
            {
                IEndSessionCallback callback = OperationContext.Current.GetCallbackChannel<IEndSessionCallback>();
                if (!subscribers.Contains(callback))
                    subscribers.Add(callback);

                int j = 0;
                foreach (IEndSessionCallback i in subscribers)
                {
                    Console.WriteLine(j + ": " + i.GetType() + " _ " + i.ToString());
                    j++;
                }
                return true;
            }
            catch
            {
                return false;
            }

        }

        public bool unsubscribe()
        {
            try
            {
                IEndSessionCallback callback = OperationContext.Current.GetCallbackChannel<IEndSessionCallback>();
                if (subscribers.Contains(callback))
                    subscribers.Remove(callback);
                return true;
            }
            catch
            {
                return false;
            }

        }

        public void startSession()
        {
            try
            {
                DAO.getInstance().startSession();
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
        }

        public bool isInWardrobe(string cpr)
        {
            try
            {
                return DAO.getInstance().isInWardRobe(cpr);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int depositClothes(string name, string adress, string zipcode, string cpr, bool? male, string birthdate)
        {
            try
            {
                int hangerNo = 
                DAO.getInstance().depositClothes(name, adress, zipcode, cpr, male, birthdate);
                backup.depositClothesBackup(name, adress, zipcode, cpr, birthdate, hangerNo);
                return hangerNo;
            }
            catch (SqlException ex)
            {
                throw new FaultException
                (
                    new FaultReason(ex.Message),
                    new FaultCode("Fejl fra databasen.")
                );
            }
        }

        public List<int> getClothesFromPerson(string hashIdentifier)
        {
            try
            {
                return DAO.getInstance().getClothesFromPerson(hashIdentifier);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void withdrawClothes(int hangerNo)
        {
            try
            {
                DAO.getInstance().withdrawClothes(hangerNo);
                backup.withdrawClothesBackup(hangerNo);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<Person> searchPersonsInWardrobe(string name, string CPR, string adress, string zipcode, string hangerNo)
        {
            try
            {
                return DAO.getInstance().searchPersonsInWardrobe(name, CPR, adress, zipcode, hangerNo);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Boolean isLicensValid()
        {
            MainServerClient remoteService = new MainServerClient();
            Boolean isLicensValid = false;

            try
            {
                isLicensValid = remoteService.isLicenseValid(DAO.getInstance().getCustomerID());
                setLastRemoteConnectionDate(DateTime.Now);
            }
            catch
            {
                DateTime lastConnection = getLastRemoteConnectionDate();
                DateTime today = DateTime.Now;
                TimeSpan dtDiff = today - lastConnection;

                if (dtDiff.Days < 14)
                {
                    return true;
                }
                else 
                { 
                    return false; 
                }
            }

            return isLicensValid;
        }

        public void setLastRemoteConnectionDate(DateTime date)
        {
            DAO.getInstance().setLastRemoteConnectionDate(date);
        }

        public void setNumberOfHangers(int numberOfHangers)
        {
            DAO.getInstance().setNumberOfHangers(numberOfHangers);
        }

        public int getNumberOfHangers()
        {
            return DAO.getInstance().getNumberOfHangers();
        }

        // Method getting all logEntries from the database (tblLog and tblPerson) and submitting them to the main server for statistical purposes 
        public bool submitLogEntries()
        {
            bool succeed = false;
            try
            {
                List<LogEntry> logEntries = DAO.getInstance().getLogEntries();
                if (logEntries.Count != 0)
                {
                    MainServerClient remoteService = new MainServerClient();
                    succeed = remoteService.submitLogEntry(logEntries.ToArray());
                    if(succeed==true)
                        DAO.getInstance().cleanLogs();
                    succeed = true;
                }
                else
                {
                    succeed = true;
                }
            }
            catch (Exception)
            {
            }
            return succeed;
        }

        public List<Hanger> getForgottenClothes()
        {
            List<Hanger> hangers;
            
            try
            {
                hangers = DAO.getInstance().getForgottenClothes();
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
            Console.WriteLine("ANTAL SUBSCRIBERS: " + subscribers.Count);
            unsubscribe();
            Console.WriteLine("ANTAL SUBSCRIBERS: " + subscribers.Count);
            if (subscribers.Count == 0)
            {
            Console.WriteLine("VI SENDER LOGGEN :D");
                submitLogEntries();
            }

            return hangers;
        }

        public void cancelDepositClothes(int hangerNo)
        {
            try
            {
                DAO.getInstance().cancelDepositClothes(hangerNo);
                backup.withdrawClothesBackup(hangerNo);
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
        }

        public DateTime getLastRemoteConnectionDate()
        {
            return DAO.getInstance().getLastRemoteConnection();
        }



    }
}